#include "pwm/timer_pwm.h"
#include "i2c/mi2c.h"
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
#include "driverlib/rom.h"
#include "key.h"
#include "lcd.h"
#include "num_str.h"

#define NUM_I2C_DATA 3


static uint32_t Receive_Data[2] = {0x01,0x01};
static uint32_t CH0_Data[20];

void I2C_Init()
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_1);
    GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, GPIO_PIN_1);

    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
//    GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_STD_WPU);
//    GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_3,GPIO_STRENGTH_8MA,GPIO_PIN_TYPE_OD);

    I2CMasterInitExpClk(I2C0_BASE, ROM_SysCtlClockGet(), false);
    I2CMasterEnable(I2C0_BASE);
}

void i2c_test()
{
    uint8_t key = EMPTY_INPUT;
    TFT_Clear(BLACK);
    while(key != KEY_BACK)
    {
        TFT_String(5,5,WHITE,BLACK,"1.send");
        TFT_String(5,25,WHITE,BLACK,"2.receive");
        TFT_String(5,45,WHITE,BLACK,"3.CH0_DATA");
        key = check_key();
        switch(key)
        {
            case 1: i2c_send_test();
                    TFT_Clear(BLACK);
                    break;
            case 2: i2c_receive_test();
                    TFT_Clear(BLACK);
                    break;
            case 3: ldc1314_CH0();
                    TFT_Clear(BLACK);
                    break;
        }
    }
    
}


void i2c_send_test()
{  
    uint8_t key = EMPTY_INPUT;
//    0001010001000001
    uint8_t Config_Data[2] = {0x14,0x41}, Clk_Div_Data[2] = {0x10,0x04};
    TFT_Clear(BLACK);
    TFT_String(5,5,WHITE,BLACK,"Press enter to begin");
    while(key != KEY_ENTER)
    {
        key = check_key();
    }
    i2c_data_send(I2C0_BASE, SLAVE_ADDRESS, Config, Config_Data, 2);
    TFT_String(5,65,WHITE,BLACK,"Sending...");
    i2c_data_send(I2C0_BASE, SLAVE_ADDRESS, CLOCK_DIVIDERS_CH0, Clk_Div_Data, 2);
    TFT_String(5,125,WHITE,BLACK,"Done!");
    while(key != KEY_BACK) key = check_key();
}

void i2c_receive_test()
{  
    uint8_t key = EMPTY_INPUT;
    unsigned char str[20];
    uint32_t Data;
    TFT_Clear(BLACK);
    TFT_String(5,5,WHITE,BLACK,"Press enter to begin");
    while(key != KEY_ENTER)
    {
        key = check_key();
    }
    TFT_String(5,65,WHITE,BLACK,"Receiving...");
    i2c_data_get(I2C0_BASE, SLAVE_ADDRESS, DEVICE_ID, Receive_Data, 2);
    TFT_String(5,125,WHITE,BLACK,"Done!");
    Data = ((Receive_Data[0]<<8)|Receive_Data[1]);
    uint322str((uint32_t)Data, str);
    TFT_String(5,185,WHITE,BLACK,str);
    i2c_data_get(I2C0_BASE, SLAVE_ADDRESS, MANUFACTURER_ID, Receive_Data, 2);
    Data = ((Receive_Data[0]<<8)|Receive_Data[1]);
    uint322str((uint32_t)Data, str);
    TFT_String(125,185,WHITE,BLACK,str);
    while(key != KEY_BACK) key = check_key();
}

void ldc1314_CH0()
{
    int i;
    uint8_t key = EMPTY_INPUT;
    unsigned char str[20];
    uint32_t Data[10];
    for (i=0; i<20; i++) CH0_Data[i] = 0x00;
    TFT_Clear(BLACK);
    TFT_String(5,5,WHITE,BLACK,"Press enter to begin");
    while(key != KEY_ENTER)
    {
        key = check_key();
    }
    i2c_data_get(I2C0_BASE, SLAVE_ADDRESS, DATA_CH0, CH0_Data, 20);
    for (i=0; i<20; i+=2)
    {
        Data[i/2] = ((CH0_Data[i]<<8)|CH0_Data[i+1]);
    }
    TFT_Clear(BLACK);
    for (i=0; i<10; i++)
    {
    uint322str((uint32_t)Data[i], str);
    TFT_String(5,5+i*20,WHITE,BLACK,str);
    }
    while(key != KEY_BACK) key = check_key();
}

void i2c_data_send(uint32_t ui32Base, uint8_t slave_addr, uint8_t reg_addr, uint8_t* data, int index)
{
     int i;

     I2CMasterSlaveAddrSet(ui32Base, slave_addr, false);
     I2CMasterDataPut(ui32Base, reg_addr);
     I2CMasterControl(ui32Base, I2C_MASTER_CMD_BURST_SEND_START);
     while(I2CMasterBusy(ui32Base));
     for (i = 0; i < index; i++)
     {
         I2CMasterDataPut(ui32Base, data[i]);
         if (i < index-1)
         {
            I2CMasterControl(ui32Base, I2C_MASTER_CMD_BURST_SEND_CONT);
         }
         else if (i == index-1) I2CMasterControl(ui32Base, I2C_MASTER_CMD_BURST_SEND_FINISH);
         while(I2CMasterBusy(ui32Base));
     }
}

void i2c_data_get(uint32_t ui32Base, uint8_t slave_addr, uint8_t reg_addr, uint32_t* data, int index)
{
    int i;
    I2CMasterSlaveAddrSet(ui32Base, slave_addr, false);
    I2CMasterDataPut(ui32Base, reg_addr);
    I2CMasterControl(ui32Base, I2C_MASTER_CMD_BURST_SEND_START);
    while(I2CMasterBusy(ui32Base));
    I2CMasterSlaveAddrSet(ui32Base, slave_addr, true);
    I2CMasterControl(ui32Base, I2C_MASTER_CMD_BURST_RECEIVE_START);
    while(I2CMasterBusy(ui32Base));
    for(i = 0;i < index; i++)
    {
        data[i] = I2CMasterDataGet(ui32Base);
        if (i < index-1)
        {            
            I2CMasterControl(ui32Base, I2C_MASTER_CMD_BURST_RECEIVE_CONT);          
        }
        else if (i == index-1) I2CMasterControl(ui32Base, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
        while(I2CMasterBusy(ui32Base));            
    }  

}
